#include "SimpleElementS.h"
#include "matrix.h"
#include "MI.h"
#include "Initial.h"

#include <vector>
#include <fstream>
#include <string>
#include <iostream>
#include <memory>

#include <Integer.h>

int MITest()
{
	using namespace std;
	using namespace CryptoPP;

	cout<<"Please input the file name:"<<endl;

	string fileName;
	cin>>fileName;
	ifstream inStream(fileName.c_str());

	if(!inStream)
	{
		cout<<"Can't open the file"<<endl;
		return 1;
	}

	size_t littileDimen,bigDimen;
	inStream>>littileDimen>>bigDimen;

	InitialDimen(littileDimen, bigDimen);

	Matrix<SimpleElementS> firstLinear(bigDimen,bigDimen), secondLinear(bigDimen,bigDimen),firstAdd(bigDimen,1),secondAdd(bigDimen,1);
	inStream>>firstLinear;
	inStream>>secondLinear;
	inStream>>firstAdd;
	inStream>>secondAdd;

//	cout<<firstLinear<<endl<<secondLinear<<endl<<firstAdd<<endl<<secondAdd<<endl;

	Integer integer;
	inStream>>integer;

	std::auto_ptr<MI> mi;
	try{
			mi.reset( new MI(littileDimen, bigDimen, firstLinear, secondLinear, firstAdd, secondAdd, integer) );
	}catch(exception& e)
	{
		cout<<e.what()<<endl;
		return 1;
	}

	vector<SimpleElementS> plain;
	vector<SimpleElementS> cipher;
	plain.resize(bigDimen);
	for (size_t i = 0; i < bigDimen; i++)
	{
		inStream>>plain[i];
	}

	cout<<"The plain:"<<endl;
	for (size_t i = 0; i < plain.size(); i++)
	{
		cout<<plain[i]<<" ";
	}
	cout<<endl;

	try{
		mi->encrypt(plain, cipher);
		cout<<"The cipher:"<<endl;
		for (size_t i = 0; i < cipher.size(); i++)
		{
			cout<<cipher[i]<<" ";
		}
		cout<<endl;

		mi->decrypt(cipher,plain);
		cout<<"The decrypt plain:"<<endl;
		for (size_t i = 0; i < plain.size(); i++)
		{
			cout<<plain[i]<<" ";
		}
		cout<<endl;

	}catch(exception& e)
	{
		cout<<e.what();
	}

	return 0;
}

// int main()
// {
// 	return MITest();
// }